Add unused access key policy#917
Conversation
c0cfdaa to
f381188
Compare
| def deactivate_user_access_keys(self, username): | ||
| """ | ||
| Deactivates all active access keys for the given IAM user. | ||
|
|
||
| Args: | ||
| username (str): IAM user name | ||
| """ | ||
| try: | ||
| access_keys = self.iam_client.list_access_keys(UserName=username)['AccessKeyMetadata'] | ||
| except Exception as e: | ||
| logger.error(f"Failed to list access keys for user '{username}': {e}") | ||
| return | ||
|
|
||
| for idx, key in enumerate(access_keys, start=1): | ||
| label = f"Access key {idx}" | ||
| current_status = key['Status'].lower() | ||
| access_key_id = key['AccessKeyId'] | ||
|
|
||
| if current_status == 'active': | ||
| try: | ||
| self.iam_client.update_access_key( | ||
| UserName=username, | ||
| AccessKeyId=access_key_id, | ||
| Status='Inactive' | ||
| ) | ||
| logger.info(f"{label} deactivated for user '{username}'") | ||
| except Exception as e: | ||
| logger.error(f"Failed to deactivate {label} for user '{username}': {e}") | ||
| else: | ||
| logger.info(f"{label} is already inactive for user '{username}'") | ||
|
|
||
| logger.info(f"Deactivate access keys for user '{username}' have been processed.") |
There was a problem hiding this comment.
We need to deactivate unused keys, not all keys. Her we should pass the inactive key_id to deactivate.
There was a problem hiding this comment.
We deactivate it by resource_id=user_name.
You can find here the way we deactivate only specific user as other policies.
Pls let me know if it is ok.
There was a problem hiding this comment.
Yeah, but if the user having multiple access_keys and one is recently used and one is used 90days back. We should delete the key that not using.
There was a problem hiding this comment.
| for username, user_data in iam_users_access_keys.items(): | ||
| last_activity_days = user_data['last_activity_days'] | ||
| # Collect age_days only for active access keys | ||
| age_days_list = [ | ||
| value[1] for key, value in user_data.items() | ||
| if key.startswith("Access key") and isinstance(value, list) and value[0] == "active" | ||
| ] | ||
| # "N/A"/None implies unused access key — fallback to UNUSED_ACCESS_KEY_MAX_DAY | ||
| age_days = min(age_days_list) if age_days_list else UNUSED_ACCESS_KEY_MAX_DAY | ||
| # if access key last_activity_days is "N/A", use age_days | ||
| if last_activity_days == "N/A": | ||
| last_activity_days = age_days | ||
| region = user_data['region'] | ||
| user_name = username |
There was a problem hiding this comment.
| for username, user_data in iam_users_access_keys.items(): | |
| last_activity_days = user_data['last_activity_days'] | |
| # Collect age_days only for active access keys | |
| age_days_list = [ | |
| value[1] for key, value in user_data.items() | |
| if key.startswith("Access key") and isinstance(value, list) and value[0] == "active" | |
| ] | |
| # "N/A"/None implies unused access key — fallback to UNUSED_ACCESS_KEY_MAX_DAY | |
| age_days = min(age_days_list) if age_days_list else UNUSED_ACCESS_KEY_MAX_DAY | |
| # if access key last_activity_days is "N/A", use age_days | |
| if last_activity_days == "N/A": | |
| last_activity_days = age_days | |
| region = user_data['region'] | |
| user_name = username | |
| for user_name, user_data in iam_users_access_keys.items(): | |
| last_activity_days = user_data['last_activity_days'] | |
| # Collect age_days only for active access keys | |
| age_days_list = [ | |
| value[1] for key, value in user_data.items() | |
| if key.startswith("Access key") and isinstance(value, list) and value[0] == "active" | |
| ] | |
| # "N/A"/None implies unused access key — fallback to UNUSED_ACCESS_KEY_MAX_DAY | |
| age_days = min(age_days_list) if age_days_list else UNUSED_ACCESS_KEY_MAX_DAY | |
| # if access key last_activity_days is "N/A", use age_days | |
| if last_activity_days == "N/A": | |
| last_activity_days = age_days | |
| region = user_data['region'] |
| elif self._policy == 'unused_access_key': | ||
| self._iam_operations.deactivate_user_access_keys(username=resource_id) |
There was a problem hiding this comment.
we need to pass the de-activate key-id.
There was a problem hiding this comment.
I pass the resource_id which contains the user_name with the unused key.
Here we collect all the suspected user_name.
|
Have you did the dry_run? |
|
I run it locally and it works ok. |
ack, yes by default it will run dry_run=yes |
f381188 to
2479a33
Compare
|
@athiruma, |
2479a33 to
eac1c68
Compare
eac1c68 to
8dc5064
Compare
Type of change
Note: Fill x in []
Description
Unused Access Key Policy:
Deactivate user access keys that are still active but have not been used in the last 90 days.
The threshold is defined by a constant parameter: UNUSED_ACCESS_KEY_DAYS = 90.
Solved Issue
For security reasons, all pull requests need to be approved first before running any automated CI